from typing import Optional, Callable, List, Any
from PySide6.QtCore import QObject, Signal
from loguru import logger

from ..models.settings_model import SettingsModel


class SettingsController(QObject):
    """设置控制器"""
    
    # 信号定义
    workspace_loaded = Signal(str)
    workspace_saved = Signal()
    contract_info_loaded = Signal(list, list)  # headers, data
    import_progress_updated = Signal(int)
    operation_completed = Signal(str, str)  # title, message
    operation_failed = Signal(str, str)  # title, message
    
    def __init__(self):
        super().__init__()
        self.model = SettingsModel()
    
    def load_workspace(self) -> None:
        """加载工作区路径"""
        try:
            workspace_path = self.model.get_workspace_path()
            if workspace_path:
                self.workspace_loaded.emit(workspace_path)
        except Exception as e:
            logger.exception(e)
            self.operation_failed.emit("加载失败", f"加载工作区路径时发生错误: {e}")
    
    def browse_and_set_workspace(self, selected_directory: str, current_path: str) -> str:
        """浏览并设置工作区路径"""
        try:
            if selected_directory and self.model.validate_workspace_path(selected_directory):
                self.model.set_workspace_path(selected_directory)
                self.operation_completed.emit("成功", "工作区路径已保存。")
                return selected_directory
            else:
                self.operation_failed.emit("无效的路径", "请选择包含 .vntrader 目录的文件夹。")
                return current_path
        except Exception as e:
            logger.exception(e)
            self.operation_failed.emit("错误", f"浏览工作区时发生错误: {e}")
            return current_path
    
    def load_contract_info(self) -> None:
        """加载合约信息"""
        try:
            data = self.model.get_contract_info()
            headers = ['合约代码', '合约乘数', '交易所', '名称']
            
            if not data.empty:
                table_data = data[['vnpy_underlying_symbol', 'contract_size', 'exchange', 'name']].values.tolist()
                self.contract_info_loaded.emit(headers, table_data)
            else:
                self.contract_info_loaded.emit(headers, [])
        except Exception as e:
            logger.exception(e)
            self.operation_failed.emit("加载失败", f"加载合约信息时发生错误: {e}")
    
    def import_contract_info(self, file_path: str) -> None:
        """导入合约信息"""
        if not file_path:
            return
            
        try:
            self.model.import_contract_info_from_file(file_path)
            self.operation_completed.emit("成功", "合约信息导入成功，重启后刷新合约信息。")
            self.load_contract_info()
        except Exception as e:
            logger.exception(e)
            self.operation_failed.emit("导入失败", f"导入合约信息时发生错误: {e}")
    
    def import_historical_data(self, workspace_path: str, file_path: str,
                             ui_progress_callback: Callable[[int], None]) -> None:
        """导入历史数据"""
        if not file_path:
            return
            
        def progress_callback(progress: int):
            self.import_progress_updated.emit(progress)
            ui_progress_callback()
        
        try:
            self.model.import_historical_data_from_file(workspace_path, file_path, progress_callback)
            self.operation_completed.emit("成功", "历史数据导入成功。")
        except Exception as e:
            logger.exception(e)
            self.operation_failed.emit("导入失败", f"导入历史数据时发生错误: {e}")